//
// Created by zhouheyu on 17-11-30.
//

#ifndef CFLRU_CFLRU_H
#define CFLRU_CFLRU_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

//关于对其操作的宏定义
#define SEC_PRE_PAGE 4
#define PAGE_PRE_BLK 64
#define SEC_PRE_BLK  256
#define CACHE_READ_DELAY 0.005
#define CACHE_WRITE_DELAY 0.005
#define FLASH_READ_DELAY 0.05
#define FLASH_WRITE_DELAY 0.25

//定义节点
typedef struct Node
{
    int LPN;
    struct Node *Pre;
    struct Node *Next;
    int isD;
}Node ,*pNode;

int buf_size;
//表示cflru队列的头部
pNode Head;
int CFLRU_CACHE_SIZE;
//相关的统计变量
int buffer_hit;
int buffer_miss_cnt;
int buffer_cnt;
int buffer_read_hit;
int buffer_read_miss;
int buffer_write_hit;
int buffer_write_miss;
int physical_read;
int physical_write;
int cache_write_num;
int cache_read_num;
//CFLRU的窗口比例alpha,w(大小)
double alpha;
int w;
//创建双向链表
pNode CreateList();
void InitVariable();
void resetCacheStat();
//判断链表是否为空
int IsEmptyList(pNode pHead);
//输出打印链表
void PrintList(pNode pHead);
//计算链表长度
int GetListLength(pNode pHead);
//删除整个链表，释放内存
void FreeList(pNode *ppHead);
//向链表中删除节点
int DeleteEleList(pNode pHead,int pos);
//从链表中找到特定的LPN值，并返回节点的指针位置,如果不存在返回NULL
pNode FindLPNinList(pNode pHead,int LPN);
//从链表中插入节点,这里之后有读写操作的operation
int InsertEleList(pNode pHead,int pos,int LPN,int operation);
//计算缓冲区的读写延迟
double ComputeCacheDelay();
//缓冲区的算法函数
double CacheManage(int secno,int scount,int operation );
//输出对应的统计结果
void PrintResultStat();

//相关的算法函数
//删除链表的尾部的数据，返回的是删除节点包含的LPN号
int DelLRUList(pNode pHead);
//该函数主要查找队列尾部的优先置换区w中是否存在干净页
//输入参数是优先置换区的大小，输出参数是干净页在队列中的位置，不存在返回NULL
pNode IsCLeanInWindow(pNode pHead,int w);
//将命中的数据页移动到MRU位置,输入参数是LRU队列和命中数据页的指针
int MoveTOLRU(pNode pHead,pNode Hit);
//将miss的请求加入到缓冲区队列,返回的物理读取的时延
double AddNewToBuffer(pNode pHead,int LPN,int operation);
//删除是制定的干净页,返回删除的LPN
int DelCleanLPN(pNode pHead,pNode CVictim);
//缓冲区满的时候将缓冲区中的数据进行移除，返回的是剔除脏页的回写时间
double DelLPNFromBuffer(pNode pHead,int w);

#endif //CFLRU_CFLRU_H
